package com.hhq.sso.common.service;

import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hhq.sso.common.domain.UserInfo;
import com.hhq.sso.common.entity.BaseEntity;
import com.hhq.sso.common.util.WebContext;
import lombok.SneakyThrows;

import java.util.Collection;
import java.util.Date;
import java.util.List;
import org.springframework.validation.annotation.Validated;
import com.hhq.sso.common.constant.CommonConstant;
import jakarta.validation.constraints.NotEmpty;

/**
 * <p>
 * Description: 业务封装基础类
 * </p>
 *
 * @author : xiaodong.yang
 * @date : 2024/6/19 15:05
 */
@Validated
public class BaseServiceImpl<M extends BaseMapper<T>, T extends BaseEntity> extends ServiceImpl<M, T>
    implements BaseService<T> {
    @Override
    public boolean save(T entity) {
        this.resolveSave(entity);
        return super.save(entity);
    }

    @Override
    public boolean saveBatch(Collection<T> entityList, int batchSize) {
        entityList.forEach(this::resolveSave);
        return super.saveBatch(entityList, batchSize);
    }

    @Override
    public boolean updateById(T entity) {
        this.resolveUpdate(entity);
        return super.updateById(entity);
    }

    @Override
    public boolean updateBatchById(Collection<T> entityList, int batchSize) {
        entityList.forEach(this::resolveUpdate);
        return super.updateBatchById(entityList, batchSize);
    }

    @Override
    public boolean deleteLogic(@NotEmpty List<Long> ids) {
        return super.removeByIds(ids);
    }

    @Override
    public boolean isFieldDuplicate(SFunction<T, ?> field, Object value, Long excludedId) {
        LambdaQueryWrapper<T> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(field, value);
        if (excludedId != null) {
            queryWrapper.ne(T::getId, excludedId);
        }
        return baseMapper.selectCount(queryWrapper) > 0;
    }

    @SneakyThrows
    private void resolveSave(T entity) {
        UserInfo user = WebContext.getUser();
        if (user != null) {
            entity.setCreateUser(user.getUserId());
            entity.setUpdateUser(user.getUserId());
        }
        Date now = DateUtil.date();
        entity.setCreateTime(now);
        entity.setUpdateTime(now);
        if (entity.getStatus() == null) {
            entity.setStatus(CommonConstant.DB_STATUS_NORMAL);
        }
        entity.setIsDeleted(CommonConstant.DB_NOT_DELETED);
    }

    @SneakyThrows
    private void resolveUpdate(T entity) {
        UserInfo user = WebContext.getUser();
        if (user != null) {
            entity.setUpdateUser(user.getUserId());
        }
        entity.setUpdateTime(DateUtil.date());
    }
}
